package com.niuwa.p2p.service.impl.business;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.mvc.entity.PageBeanWithTitle;
import com.niuwa.p2p.core.utils.CalculateBusiUtils;
import com.niuwa.p2p.core.utils.DictUtil;
import com.niuwa.p2p.core.utils.StringUtil;
import com.niuwa.p2p.dao.business.InvestDao;
import com.niuwa.p2p.dao.business.InvestProdRecordDao;
import com.niuwa.p2p.dao.business.LoanClaimDao;
import com.niuwa.p2p.entity.PageQuery;
import com.niuwa.p2p.entity.business.LoanClaim;
import com.niuwa.p2p.entity.business.LoanClaimLog;
import com.niuwa.p2p.exception.BusinessException;
import com.niuwa.p2p.service.business.ILoanClaimInnerService;
import com.niuwa.p2p.service.business.ILoanClaimService;
//import com.niuwa.p2p.service.exchange.IMatchService;
import com.niuwa.p2p.vo.business.LoanClaimOriginVo;
import com.niuwa.p2p.vo.business.LoanClaimTitleVo;
import com.niuwa.p2p.vo.business.LoanClaimVo;

import static com.niuwa.p2p.core.utils.DictConstant.*;

@Service
public class LoanClaimServiceImpl implements ILoanClaimService {
	private final Logger logger = Logger.getLogger(LoanClaimServiceImpl.class);
	
	/**
	 *0:日期类型
	 *1:月类型 
	 */
	private static String TIME_TYPE[] = {"D","M"};
	
	/**
	 * 还款状态类型
	 */
	private static String DICT_TYPE = "REPAY_STATUS";
	@Autowired
	private LoanClaimDao loanClaimDao;

	@Autowired
	private InvestDao investDao;

	@Autowired
	private ILoanClaimInnerService lcInnerService;
	
//	@Autowired
//	private IMatchService matchService;
	@Autowired
	private InvestProdRecordDao investProdRecordDao;
	@Override
	public void updateLoanClaimStatus(Map<String, Object> paramMap) throws Exception {
		loanClaimDao.updateLoanClaimStatus(paramMap);
	}

	@Override
	public int updateDirectPublish(String[] projectNoList, LoanClaimLog logBean){
		int count = 0;
		logBean.setOperateType(ClaimOperateType.DIRECT_RELEASE.getCode());
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("projectToOld", ProjectTo.NO_ASSIGN);
		paramMap.put("releaseStatusNew", ReleaseStatus.WAIT_APPLY);
		paramMap.put("projectToNew", ProjectTo.FRONT);
		boolean hasError=false;
		for (String projectNo : projectNoList) {
			try {
				int tc = lcInnerService.batchInnerUpdateDirectPublish(paramMap, projectNo, logBean);
				count+=tc;
				if(tc==0)
					logger.info("直投发布无效，项目状态已发生变更，项目编号:"+projectNo);
			} catch (Exception e) {
				hasError=true;
				logger.error("直投发布失败，项目编号:"+projectNo, e);
			}
		}
		if(hasError && count==0){
			throw new RuntimeException("直投发布全部失败！");
		}
		if(count==0){
			throw new BusinessException("business.datachanged.all");
		}
		if(count<projectNoList.length){
			throw new BusinessException("business.datachanged.section");
		}
		return count;
	}

	@Override
	public int updateBackMatch(String[] projectNoList, LoanClaimLog logBean){
		List<Map<String, String>> loanlist=new LinkedList<Map<String,String>>();
		int count = 0;
		logBean.setOperateType(ClaimOperateType.BACK_MATCH.getCode());
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("projectToOld", ProjectTo.NO_ASSIGN);
		paramMap.put("releaseStatusNew", ReleaseStatus.NO_MATCH);// 未匹配
		paramMap.put("projectToNew", ProjectTo.BACK);
		boolean hasError=false;
		for (String projectNo : projectNoList) {
			try {
				int tc = lcInnerService.batchInnerUpdateBackMatch(paramMap, projectNo, logBean);
				count+=tc;
				if(tc==0){
					logger.info("后台匹配无效，项目状态已发生变更，项目编号:"+projectNo);
				}else{
					LoanClaim lc=loanClaimDao.selectByPrimaryKey(projectNo);
					String loanUserId=lc.getCustId()==null?lc.getCorpNo(): String.valueOf(lc.getCustId());//个人或企业借款
					BigDecimal loanAmount=ProjectType.LOAN.getCode().equals(lc.getProjectType()) ? lc.getLoanAmount() : lc.getRemainClaimAmount();//借款金额或债权余额
					BigDecimal lowPlatformFee=lc.getLowPlatformFee();//借款平台最低费用
					BigDecimal platformRate=lc.getPlatformRate(); //借款平台服务费率
					loanAmount=loanAmount.add(CalculateBusiUtils.LoanServiceCharge(loanAmount, platformRate, lowPlatformFee));//借款金额+平台服务费
					Map<String, String> map=new HashMap<String, String>();
					map.put("_id", lc.getProjectNo());
					map.put("user_id",loanUserId);
					map.put("loan_amount", loanAmount.toPlainString());
					map.put("version", String.valueOf(lc.getVersion()));
					loanlist.add(map);
				}
			} catch (Exception e) {
				hasError=true;
				logger.error("后台匹配失败，项目编号:"+projectNo, e);
			}
		}
		if(hasError && count==0){
			throw new RuntimeException("后台匹配全部失败！");
		}
		if(count==0){
			throw new BusinessException("business.datachanged.all");
		}
		
		//添加项目到后台队列
//		matchService.doAddLoan(loanlist);
		
		if(count<projectNoList.length){
			throw new BusinessException("business.datachanged.section");
		}
		return count;
	}

	@Override
	public int updateRejectProject(String[] projectNoList, LoanClaimLog logBean){
		int count = 0;
		logBean.setOperateType(ClaimOperateType.REJECT_PROJECT.getCode());
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("projectToOld", ProjectTo.NO_ASSIGN);
		paramMap.put("releaseStatusNew", ReleaseStatus.REJECT_AUDIT);
		paramMap.put("projectToNew", ProjectTo.APPROVAL_SYS);
		boolean hasError=false;
		for (String projectNo : projectNoList) {
			try {
				int tc = lcInnerService.batchInnerUpdateRejectProject(paramMap, projectNo, logBean);
				count+=tc;
				if(tc==0)
					logger.info("退回审批系统无效，项目状态已发生变更，项目编号:"+projectNo);
			} catch (Exception e) {
				hasError=true;
				logger.error("退回审批系统失败，项目编号:"+projectNo, e);
			}
		}
		if(hasError && count==0){
			throw new RuntimeException("退回审批系统全部失败！");
		}
		if(count==0){
			throw new BusinessException("business.datachanged.all");
		}
		if(count<projectNoList.length){
			throw new BusinessException("business.datachanged.section");
		}
		return count;
	}

	/**
	 * 分页查询借款债权集合 根据paramMap，选取需要的借款债权集合
	 * 
	 * @param paramMap
	 *            过滤得条件Map
	 * @return PageBean<LoanClaimTitleVo, LoanClaimVo> 借款债权Title信息与待匹配资金 分页信息集合
	 */
	@Override
	public PageBeanWithTitle<LoanClaimTitleVo, LoanClaimVo> search(Map<String, Object> paramMap) {

		assert paramMap.get(PageQuery.PAGEQUERY) != null;

		int totalCount = loanClaimDao.count(paramMap);

		PageBeanWithTitle<LoanClaimTitleVo, LoanClaimVo> page = new PageBeanWithTitle<LoanClaimTitleVo, LoanClaimVo>(totalCount);

		// 设置当前页
		page.setPage(((PageQuery) paramMap.get(PageQuery.PAGEQUERY)).getPage());

		page.setRows(loanClaimDao.selectLoanClaimBySelective(paramMap));

		page.setTitleItem(getLoanClaimTitleSummerItem());

		return page;
	}

	/**
	 * 通过债权项目编号 选取单个借款债权详情
	 * 
	 * @param projectNo
	 *            项目编号
	 * @return LoanClaimOriginVo 借款债权详情
	 */
	@Override
	public LoanClaimOriginVo getClaimLoanOriginDetailByProjectNo(String projectNo) {
		return loanClaimDao.selectClaimLoanDetailByProjectNo(projectNo);
	}

	/**
	 * 取得借款债权Title的合计项目
	 * 
	 * @return LoanClaimTitleVo 借款债权Title的合计项目
	 */
	@Override
	public LoanClaimTitleVo getLoanClaimTitleSummerItem() {
		LoanClaimTitleVo loanClaimTitleVo = new LoanClaimTitleVo();
		loanClaimTitleVo.setToAssignAmout(investProdRecordDao.getWaitMatchFund()== null ? BigDecimal.ZERO : investProdRecordDao.getWaitMatchFund());
		loanClaimTitleVo.setToAssignClaimAmout(loanClaimDao.selectToAssignClaimAmout() == null ? BigDecimal.ZERO : loanClaimDao.selectToAssignClaimAmout());
		loanClaimTitleVo.setToAssignLoanAmout(loanClaimDao.selectToAssignLoanAmout() == null ? BigDecimal.ZERO : loanClaimDao.selectToAssignLoanAmout());
		return loanClaimTitleVo;
	}

	@Override
	public LoanClaim selectByPrimaryKey(String projectNo) {
		//期限类型
		LoanClaim loanClaim = loanClaimDao.selectByPrimaryKey(projectNo);
		String timeTye = loanClaim.getTimeType();
		timeTye = (StringUtil.isNullOrEmpty(timeTye)?"M":timeTye);
		//设置借款期限
		if(timeTye.equals(TIME_TYPE[0])){//天
			loanClaim.setLoanTermStr((loanClaim.getLoanTerm()==null?0:loanClaim.getLoanTerm())+"天");
		}else if(timeTye.equals(TIME_TYPE[1])){//月
			loanClaim.setLoanTermStr((loanClaim.getLoanTerm()==null?0:loanClaim.getLoanTerm())+"月");
		}else{
			
		}
		//设置还款状态
		String repayStatusLocal = DictUtil.getDictNameByTypeAndCode(DICT_TYPE, loanClaim.getRepayStatus());
		if(StringUtil.isNullOrEmpty(repayStatusLocal)){
		}else{
			loanClaim.setRepayStatus(repayStatusLocal);
		}
		//设置提前还款手续费 计算规则：借款人核准金额×提前还款平台管理费
		BigDecimal approveAmount = loanClaim.getApproveAmount();
		
		BigDecimal earlyPayRate = loanClaim.getEarlyPayRate();
		
		if(approveAmount==null||earlyPayRate==null){
			loanClaim.setEarlyPayPlateformFee("0元");
		}else{
			BigDecimal earlyPayPlateformFee = approveAmount.add(earlyPayRate);
			java.text.DecimalFormat myformat=new java.text.DecimalFormat("0.00");
			String str = myformat.format(earlyPayPlateformFee);    
			loanClaim.setEarlyPayPlateformFee(str+"元");
		}
		return loanClaimDao.selectByPrimaryKey(projectNo);
	}

}
